package view;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Line2D;
import java.util.ArrayList;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

import model.Lap;
import controller.Controladora;

public class PlotCircuit extends JPanel {

	private static final long serialVersionUID = 1L;
	private Controladora controladora;
	private int[] coordenadaSortida = {-1,-1};
	private int[] coordenadaFinalTram = {-1,-1};
	private JButton btnConfirm = new JButton("Confirm");
	private JLabel jlInfo = new JLabel("                                             Load a circuit");
	private boolean sortidaFixada = false;
	private boolean init = false;
	private int xPunt = -10000;
	private int yPunt = -10000;
	private int xPuntFinal = -10000;
	private int yPuntFinal = -10000;
	private JRadioButton jr1 = new JRadioButton("All Circuit");
	private JRadioButton jr2 = new JRadioButton("One Stretch");
	private ButtonGroup bgRadios = new ButtonGroup();
	private JPanel radiobuttons = new JPanel();
	
	public PlotCircuit(Controladora c) {
        crearJPanelIzquierda();
        crearJPanelDerecha();
        this.setVisible(true);
        controladora = c;
        jlInfo.setVisible(true);
        jlInfo.setForeground(new Color(53, 53, 53));
        jlInfo.setFont(new Font("Georgia", Font.BOLD, 36));
        btnConfirm.setEnabled(false);
        add(radiobuttons, BorderLayout.EAST);
        add(btnConfirm, BorderLayout.SOUTH);
        add(jlInfo, BorderLayout.CENTER);
    }
	
	/**
	 * Crear el panell de l'esquerra
	 */
    public void crearJPanelIzquierda() {
    	this.setPreferredSize(new Dimension(1024, 600));
    	this.setLayout( new BorderLayout());
    	this.setBackground(Color.BLACK);
    	crearListenerJPanelIzquierda();
    }
    
    /**
     * Crear el panell de la dreta
     */
    public void crearJPanelDerecha(){
    	radiobuttons.setLayout(new GridLayout(10, 1));
    	radiobuttons.setVisible(true);
    	radiobuttons.setBackground(Color.DARK_GRAY);
    	jr1.setEnabled(false);
        jr2.setEnabled(false);
        jr1.setSelected(true);
        jr2.setSelected(false);
        bgRadios.add(jr1);
        bgRadios.add(jr2);
        radiobuttons.add(jr1);
        radiobuttons.add(jr2);
        
        jr1.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				repaint();
			}
		});
        jr2.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				repaint();
			}
		});
    }
    
    @Override
	public void paintComponent(Graphics g){
		super.paintComponent(g);

		Graphics2D graphics = (Graphics2D) g;
		
		if (sortidaFixada) {
			pintaLaps(graphics, jr2.isSelected());
		} else {
			pintaCircuit(graphics);
			
			if (xPunt != -10000) {
				pintaPunt(xPunt, yPunt, graphics, Color.RED);
			}
			
			if (xPuntFinal != -10000 && jr2.isSelected()) {
				pintaPunt(xPuntFinal, yPuntFinal, graphics, Color.GREEN);
			}
		}
		
	}

    /**
     * Crea els listeners del panell esquerra
     */
    public void crearListenerJPanelIzquierda(){
    	
    	this.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {}

			@Override
			public void mousePressed(MouseEvent e) {
				if (!sortidaFixada && init && jr1.isSelected()) {
	            	coordenadaSortida[0] = Math.round(e.getX());
	                coordenadaSortida[1] = Math.round(e.getY());
	            	
	                double[] puntCircuit = controladora.calculaPuntSortida(coordenadaSortida[0], coordenadaSortida[1]);
	                xPunt = (int)puntCircuit[0];
	                yPunt = (int)puntCircuit[1];
	                repaint();
	                btnConfirm.setEnabled(true);
            	} else if (!sortidaFixada && init && jr2.isSelected()) {
            		if (e.getButton() == MouseEvent.BUTTON1) {
            			coordenadaSortida[0] = Math.round(e.getX());
    	                coordenadaSortida[1] = Math.round(e.getY());
    	            	
    	                double[] puntCircuit = controladora.calculaPuntSortida(coordenadaSortida[0], coordenadaSortida[1]);
    	                xPunt = (int)puntCircuit[0];
    	                yPunt = (int)puntCircuit[1];
    	                repaint();
    	                btnConfirm.setEnabled(true);
            		} else if (e.getButton() == MouseEvent.BUTTON3) {
            			coordenadaFinalTram[0] = Math.round(e.getX());
    	                coordenadaFinalTram[1] = Math.round(e.getY());
    	            	
    	                double[] puntCircuit = controladora.calculaPuntFinal(coordenadaFinalTram[0], coordenadaFinalTram[1]);
    	                xPuntFinal = (int)puntCircuit[0];
    	                yPuntFinal = (int)puntCircuit[1];
    	                repaint();
    	                btnConfirm.setEnabled(true);
            		}
            	}
			}

			@Override
			public void mouseReleased(MouseEvent e) {}

			@Override
			public void mouseEntered(MouseEvent e) {}

			@Override
			public void mouseExited(MouseEvent e) {}
        });
		
    	btnConfirm.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (!sortidaFixada) {
					sortidaFixada = true;
					if (jr1.isSelected()){
						controladora.numeroDeVoltes();
					} else {
						controladora.numeroDeTrams();
					}
					getParent().repaint();
					jr1.setEnabled(false);
					jr2.setEnabled(false);
				}
			}
		});
    }
    
    /**
	 * Pinta el circuit
	 */
	public void pintaCircuit(Graphics2D graphics) {
		for (int i = 0; i < controladora.getCoordCartesianas().size() - 1;i++) {
			if (i != controladora.getCoordCartesianas().size() - 1) {
				pintaLinia(controladora.getCoordCartesianas().get(i)[0], controladora.getCoordCartesianas().get(i)[1], controladora.getCoordCartesianas().get(i+1)[0], controladora.getCoordCartesianas().get(i+1)[1], new Color(255, 255, 255), graphics);
			} else {
				pintaLinia(controladora.getCoordCartesianas().get(i)[0], controladora.getCoordCartesianas().get(i)[1], controladora.getCoordCartesianas().get(0)[0], controladora.getCoordCartesianas().get(0)[1] , new Color(255, 255, 255), graphics);
			}
		}
	}
	
	/**
	 * Pinta les laps
	 */
	public void pintaLaps(Graphics2D graphics, boolean trams) {
		Lap lap = new Lap();
		int nActiveLaps = controladora.getCircuit().numberOfActiveLaps();
		ArrayList<Lap> laps = controladora.getCircuit().getLaps();
		for (int i = 0; i < laps.size() ;i++) {
			lap = laps.get(i);
			Color color = new Color(lap.getRgb()[0], lap.getRgb()[1], lap.getRgb()[2]);
			
			for (int j = 0; j < lap.getGgas().size() - 1 && lap.isMostrar(); j++) {
				double[] coord = lap.getGgas().get(j).getCartesiana();
				float maxSpeed = lap.getMax_vel();
				float speed = lap.getRmcs().get(j).getSpeed() / maxSpeed;
				
				if (nActiveLaps == 1) {
					int red = Math.round(128*(1-speed));
					int green = Math.round(128*speed);
					color = new Color(red, green, 0);
				}
				
				if (j != lap.getGgas().size() - 2) {
					double[] coord2 = lap.getGgas().get(j+1).getCartesiana();
					pintaLinia((coord[0]+i*10), coord[1], coord2[0]+i*10, coord2[1], color, graphics);
				} else if (!trams) {
					pintaLinia((coord[0]+i*10 ), coord[1], lap.getGgas().get(0).getCartesiana()[0]+i*10, lap.getGgas().get(0).getCartesiana()[1], color, graphics);
				}
			}
			
		}
	}
    
	/**
	 * Pinta una linia a partir de dos punts. 
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 * @param color
	 * @param g
	 */
	public void pintaLinia(double x1, double y1, double x2, double y2, Color color, Graphics2D g) {
		BasicStroke stroke = new BasicStroke((float)0.8);
	    g.setStroke(stroke);
		g.setColor(color);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Line2D lin = new Line2D.Double(x1, y1, x2, y2);
        g.draw(lin);
    }

	/**
	 * @return the coordenadaSortida
	 */
	public int[] getCoordenadaSortida() {
		return coordenadaSortida;
	}

	/**
	 * @param coordenadaSortida the coordenadaSortida to set
	 */
	public void setCoordenadaSortida(int[] coordenadaSortida) {
		this.coordenadaSortida = coordenadaSortida;
	}

	public void pintaPunt(int x, int y, Graphics2D g, Color color) {
		g.setColor(color);
		g.fillOval(x-8, y-8, 15, 15);
	}

	/**
	 * @param sortidaFixada the sortidaFixada to set
	 */
	public void setSortidaFixada(boolean sortidaFixada) {
		this.sortidaFixada = sortidaFixada;
	}
	
	/**
	 * @param xPunt the xPunt to set
	 */
	public void setxPunt(int xPunt) {
		this.xPunt = xPunt;
	}

	/**
	 * @param yPunt the yPunt to set
	 */
	public void setyPunt(int yPunt) {
		this.yPunt = yPunt;
	}

	/**
	 * 
	 * @param init
	 */
	public void setInit(boolean init) {
		this.init = init;
	}
	
	/**
	 * Activa els radio buttons
	 */
	public void loadCircuit() {
		jr1.setEnabled(true);
        jr2.setEnabled(true);
		remove(jlInfo);
	}
	
	
}
